package com.thread.syn3;

/**
 * 并发:多个线程访问同一个资源
 *线程同步2种方式
 * 1.方法上使用synchronized关键字
 * 2.使用synchronized（）{} 代码块
 * @author jiangbang
 * @date 2016/7/21
 */
public class SynDemo01 implements Runnable{
    private int num = 50;
    private boolean flag = true;

    @Override
    public void run() {
        while(flag){
            test2();
        }
    }


    //synchronize锁定不正确 不安全
    public  void test4() {
        //a b c  a进去了   bc在等待
        synchronized (this){
            if(num<=0){
                flag = false;//跳出循环
                return;
            }
        }
        // a才走到这里  b就解锁了    导致ab 在这里抢资源
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"抢到啦"+num--);


    }

    //synchronize同步块 变成线程安全
    public  void test3() {
        synchronized (this){
            if(num<=0){
                flag = false;//跳出循环
                return;
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"抢到啦"+num--);
        }

    }


    //加一个synchronized关键字 变成线程安全
    public synchronized void test2() {
        if(num<=0){
            flag = false;//跳出循环
            return;
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"抢到啦"+num--);
    }

    //线程不安全
    public void test1() {
        if(num<=0){
            flag = false;//跳出循环
        }
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"抢到啦"+num--);
    }

    public static void main(String[] args) {
        //真实角色   并发现象
        SynDemo01 runnableImpl2 = new SynDemo01();
        //代理角色
        Thread thread1 = new Thread(runnableImpl2,"A");
        Thread thread2 = new Thread(runnableImpl2,"B");
        Thread thread3 = new Thread(runnableImpl2,"C");
        //启动线程
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
